from datetime import datetime
from decimal import Decimal
from django.contrib.auth.models import User
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models, transaction
from rangevoting.managers import VoteManager, VoteSummaryManager

VOTE_RANGE = (Decimal("0.0"), Decimal("10.0"))

class Vote(models.Model):
    """
    ``Vote`` defines a generic 'vote' that
    can be cast on any Django model, 
    with a score up to 10.0
    """
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    score = models.DecimalField(max_digits=5, decimal_places=2)
    created_date = models.DateTimeField(default=datetime.now)
    content_object = generic.GenericForeignKey()

    objects = VoteManager()

    class Meta:
        ordering = ('-created_date', '-id')
        unique_together = (('user', 'content_type', 'object_id'),)
    
    def __unicode__(self):
        return "%s for %s" % (self.score, unicode(self.content_object)) 

    @transaction.commit_on_success
    def save(self, force_insert=False, force_update=False):
        """
        Update the ``VoteSummary``
        """
        super(Vote, self).save(force_insert, force_update)

        summary = VoteSummary.objects.get(
            content_type = self.content_type,
            object_id = self.object_id
        )
        
        summary.vote_count += 1
        summary.vote_sum += Decimal(self.score)
        summary.save()

    @transaction.commit_on_success
    def delete(self):
        summary = VoteSummary.objects.get(
            content_type = self.content_type,
            object_id = self.object_id
        )
        
        summary.vote_count -=1
        summary.vote_sum -= self.score
        summary.save()

        super(Vote, self).delete()


class VoteSummary(models.Model):
    """
    Summary table for ``Vote`` 
    """
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    vote_count = models.PositiveIntegerField(default=0)
    vote_sum = models.DecimalField(max_digits=9, decimal_places=2, default="0.0")
    created_date = models.DateTimeField(default=datetime.now)
    content_object = generic.GenericForeignKey()

    objects = VoteSummaryManager()

    class Meta:
        ordering = ('-id',)
        unique_together = (('content_type', 'object_id'),)

    def __unicode__(self):
        return unicode(self.content_object)
